home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’89 / gadlife / source (ugly) / patch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-01  |  7.1 KB  |  275 lines  |  [TEXT/KAHL]

  1. #include "main.h"
  2. #include "patch.h"
  3.  
  4. extern int        isBackground;
  5. extern long    oldWaitMouse, oldStillDown, oldAvail, oldDelay;
  6. extern int        waitTrapOn, delayTrapOn;
  7.  
  8. implemented( whichTrap ) {
  9.     return( NGetTrapAddress( whichTrap, ToolTrap ) != NGetTrapAddress( UnImplTrapNum, ToolTrap ));
  10. }
  11.  
  12. getMBarHeight() {
  13.     return( implemented( ScriptsTrapNum ) ? GetMBarHeight() : MBarHeight );
  14. }
  15.  
  16. /*******************************************************
  17. *                                                                *
  18. *    InApplHeap should return true if the address passed it is between the beginning    *
  19. *    and end of the current application heap, and false otherwise.  It can be used to    *
  20. *    detect whether an application patch has been installed on a trap.                *
  21. *                                                                *
  22. *    Note that as written, with the standard compiler glue, this depends on globals,    *
  23. *    which strictly speaking is not so cool.  Instead, I could use the current stack    *
  24. *    pointer as an upper bound (although this may be a bad assumption on a possible    *
  25. *    virtual memory machine), and the HandleZone of a handle I have allocated as a    *
  26. *    lower bound.  For example, the HandleZone of GetMHandle of the file menu.        *
  27. *                                                                *
  28. *******************************************************/
  29.  
  30. inApplHeap( addr )
  31.     long            addr;
  32. {
  33.     return( addr > ( long )ApplicZone() && addr < ( long )GetApplLimit() );
  34. }
  35.  
  36. /*******************************************************
  37. *                                                                *
  38. *    This installs theCode as a patch on the trap, with the intermediate routine in    *
  39. *    the ptch resource of id how.  flag specifies either OSTrap or ToolTrap.  Within    *
  40. *    the application, patches override each other, rather than nesting.  The routine    *
  41. *    specified by how is one of:                                        *
  42. *                                                                *
  43. *        replacePatchID:    theCode entirely replaces the original trap code.        *
  44. *        filterPatchID:    theCode is called before jumping to the original code.        *
  45. *        eitherPatchID:    theCode is called, and the C return code specifies which.    *
  46. *                                                                *
  47. *    In the last case, the return code is either patchContinue or patchReturn.  Note    *
  48. *    that the above routines only work for the stack based traps.  If you use the    *
  49. *    replace routine, theCode should be a pascal function with the same arguments    *
  50. *    as the trap being patched, and return normally.  If you use the filter routine,    *
  51. *    theCode should either be a C function with arguments reversed which returns    *
  52. *    normally, or a pascal function which returns abnormally (unlk, rts).  If you    *
  53. *    use the either routine, the function should be in pascal, and depending on the    *
  54. *    result returned in d0, either return normally or abnormally.                *
  55. *                                                                *
  56. *******************************************************/
  57.  
  58. installPatch( trap, flag, theCode, how )
  59.     long            theCode;
  60.     int            trap, how, flag;
  61. {
  62.     patchHandle    thePatchHand;
  63.     patchPtr        thePatch;
  64.     long            original, myA5, oldPatch;
  65.     
  66.     oldPatch = NGetTrapAddress( trap, flag );
  67.     if( inApplHeap( oldPatch )) {
  68.         original = (( patchPtr )oldPatch )->original;
  69.     } else {
  70.         original = oldPatch;
  71.         oldPatch = NULL;
  72.     }
  73.     if( !oldPatch || (( patchPtr )oldPatch )->patch != theCode ) {
  74.         thePatchHand = ( patchHandle )GetResource( 'ptch', how );
  75.         DetachResource( thePatchHand );
  76.         HLock( thePatchHand );
  77.         thePatch = *thePatchHand;
  78.         asm {
  79.             move.l    a5,myA5
  80.         }
  81.         thePatch->count = 1;
  82.         thePatch->myA5 = myA5;
  83.         thePatch->patch = theCode;
  84.         thePatch->original = original;
  85.         thePatch->oldPatch = oldPatch;
  86.         NSetTrapAddress( thePatch, trap, flag );
  87.     } else thePatch->count++;
  88. }
  89.  
  90. /*******************************************************
  91. *                                                                *
  92. *    This removes the most recent patch on trap, where flag is as above.  If the last    *
  93. *    patch using the particular intermediate routine is removed, it is disposed of.    *
  94. *    The initial check allows this to be called more times than strictly neccessary,    *
  95. *    but one should be *very* careful when doing this.                        *
  96. *                                                                *
  97. *******************************************************/
  98.  
  99. removePatch( trap, flag )
  100.     int            trap, flag;
  101. {
  102.     patchHandle    thePatchHand;
  103.     patchPtr        thePatch;
  104.     
  105.     thePatch = ( patchPtr )NGetTrapAddress( trap, flag );
  106. /*    if( inApplHeap( thePatch ))
  107. */        if( ! --( thePatch->count )) {
  108.             if( thePatch->oldPatch ) NSetTrapAddress( thePatch->oldPatch, trap, flag );
  109.             else NSetTrapAddress( thePatch->original, trap, flag );
  110.             thePatchHand = ( patchHandle )RecoverHandle( thePatch );
  111.             DisposHandle( thePatchHand );
  112.         }
  113. }
  114.  
  115. /*******************************************************
  116. *                                                                *
  117. *                                                                *
  118. *******************************************************/
  119.  
  120. doDelay( numTicks, finalTicks )
  121.     long        numTicks, *finalTicks;
  122.     {
  123.     long        ticks, endTicks;
  124.     int        diff;
  125.     
  126.     if( isBackground )
  127.         {
  128.         ticks = TickCount();
  129.         endTicks = ticks + numTicks;
  130.         while(( diff = endTicks - ticks ) > 0 ) {
  131.             doBackground( diff, noGray, NULL );
  132.             ticks = TickCount();
  133.         }
  134.         *finalTicks = ticks;
  135.         return( *finalTicks );
  136.         }
  137.     else    Delay( numTicks, finalTicks );
  138.     }
  139.  
  140. doDelayTrap()
  141.     {
  142.     long    finalTicks, numTicks;
  143.     asm    {
  144.         movem.l    d3-d7/a2-a5,-(sp)
  145.         move.l    CurrentA5,a5
  146.         }
  147.     if( isBackground )
  148.         {
  149.         asm    {
  150.             move.l    a0,numTicks
  151.             }
  152.         doDelay( numTicks, &finalTicks );
  153.         asm    {
  154.             move.l    finalTicks,d0
  155.             movem.l    (sp)+,d3-d7/a2-a5
  156.             unlk        a6
  157.             rts
  158.             }
  159.         }
  160.     else    asm    {
  161.             move.l    oldDelay,a1
  162.             movem.l    (sp)+,d3-d7/a2-a5
  163.             unlk        a6
  164.             jmp        (a1)
  165.             }
  166.     }
  167.  
  168. doWaitMouse()
  169.     {
  170.     int        temp;
  171.     asm    {
  172.         movem.l    d0-d7/a1-a5,-(sp)
  173.         move.l    CurrentA5,a5
  174.         }
  175.     doBackground( lotsElseToDo, noGray, NULL );
  176.     asm    {
  177.         move.l    oldWaitMouse,a0
  178.         movem.l    (sp)+,d0-d7/a1-a5
  179.         unlk        a6
  180.         jmp        (a0)
  181.         }
  182.     }
  183.  
  184. doWaitClean()
  185.     {
  186.     int        temp;
  187.     asm    {
  188.         movem.l    d0-d7/a1-a5,-(sp)
  189.         move.l    CurrentA5,a5
  190.         }
  191.     doBackground( lotsElseToDo, noGray, NULL );
  192.     asm    {
  193.         move.l    oldStillDown,a0
  194.         movem.l    (sp)+,d0-d7/a1-a5
  195.         unlk        a6
  196.         jmp        (a0)
  197.         }
  198.     }
  199.  
  200. doAvail()
  201.     {
  202.     int        temp;
  203.     asm    {
  204.         movem.l    d0-d7/a1-a5,-(sp)
  205.         move.l    CurrentA5,a5
  206.         }
  207.     doBackground( lotsElseToDo, noGray, NULL );
  208.     asm    {
  209.         move.l    oldAvail,a0
  210.         movem.l    (sp)+,d0-d7/a1-a5
  211.         unlk        a6
  212.         jmp        (a0)
  213.         }
  214.     }
  215.  
  216. pascal long doDragGray( startRgn, startPt, limitRect, slopRect, axis )
  217.     RgnHandle        startRgn;
  218.     Point            startPt;
  219.     Rect            *limitRect, *slopRect;
  220.     int            axis;
  221.     {
  222.     long            result;
  223.  
  224.     asm    {
  225.         movem.l    d0-d7/a1-a5,-(sp)
  226.         move.l    CurrentA5,a5
  227.         }
  228.     setDragPat( gray );
  229.     result = doDragTheRgn( startRgn, startPt, limitRect, slopRect, axis );
  230.     asm    {
  231.         movem.l    (sp)+,d0-d7/a1-a5
  232.         unlk        a6
  233.         move.l    (sp)+,a0
  234.         move.l    result,(sp)
  235.         jmp        (a0)
  236.         }
  237.     }
  238.  
  239. installDelayTrap() {
  240.     if( !delayTrapOn ) {
  241.         oldDelay = NGetTrapAddress( DelayTrapNum, OSTrap );
  242.         NSetTrapAddress( doDelayTrap, DelayTrapNum, OSTrap );
  243.     }
  244.     ++delayTrapOn;
  245. }
  246.  
  247. removeDelayTrap() {
  248.     if( delayTrapOn == 1 )
  249.         NSetTrapAddress( oldDelay, DelayTrapNum, OSTrap );
  250.     if( delayTrapOn > 0 ) --delayTrapOn;
  251. }
  252.  
  253. installWaitTrap() {
  254.     if( !waitTrapOn ) {
  255.         oldStillDown = NGetTrapAddress( StillDownTrapNum, ToolTrap );
  256.         NSetTrapAddress( doWaitClean, StillDownTrapNum, ToolTrap );
  257.     }
  258.     ++waitTrapOn;
  259. }
  260.  
  261. removeWaitTrap()
  262.     {
  263.     if( waitTrapOn == 1 )
  264.         NSetTrapAddress( oldStillDown, StillDownTrapNum, ToolTrap );
  265.     if( waitTrapOn > 0 ) --waitTrapOn;
  266.     }
  267.     
  268. installAvailTrap() {
  269.     oldAvail = NGetTrapAddress( AvailTrapNum, ToolTrap );
  270.     NSetTrapAddress( doAvail, AvailTrapNum, ToolTrap );
  271. }
  272.     
  273. removeAvailTrap() {
  274.     NSetTrapAddress( oldAvail, AvailTrapNum, ToolTrap );
  275. }